{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.        ,  1.        ,  0.        ,  1.        ],\n",
       "       [ 0.84147098,  0.54030231,  0.09983342,  0.99500417],\n",
       "       [ 0.90929743, -0.41614684,  0.19866933,  0.98006658],\n",
       "       [ 0.14112001, -0.9899925 ,  0.29552021,  0.95533649],\n",
       "       [-0.7568025 , -0.65364362,  0.38941834,  0.92106099]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "def getPositionEncoding(seq_len, d, n=10000):\n",
    "    P = np.zeros((seq_len, d))\n",
    "    for k in range(seq_len):\n",
    "        for i in np.arange(int(d/2)):\n",
    "            denominator = np.power(n, 2*i/d)\n",
    "            P[k, 2*i] = np.sin(k/denominator)\n",
    "            P[k, 2*i+1] = np.cos(k/denominator)\n",
    "    return P\n",
    "getPositionEncoding(seq_len=5, d=4, n=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.          1.          0.          1.        ]\n",
      " [ 0.84147098  0.54030231  0.09983342  0.99500417]\n",
      " [ 0.90929743 -0.41614684  0.19866933  0.98006658]\n",
      " [ 0.14112001 -0.9899925   0.29552021  0.95533649]\n",
      " [-0.7568025  -0.65364362  0.38941834  0.92106099]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "def getPositionEncoding(seq_len, d, n=10000):\n",
    "    \"\"\"\n",
    "    d (int): 模型的维度（即每个位置的特征数量）\n",
    "    n (int): 缩放因子，用于调整位置编码的频率（默认值为 10000）\n",
    "    返回:\n",
    "    P (numpy.ndarray): 位置编码矩阵，形状为 (seq_len, d)\n",
    "    \"\"\"\n",
    "    # 初始化一个形状为 (seq_len, d) 的零矩阵 P\n",
    "    P = np.zeros((seq_len, d))\n",
    "    \n",
    "    # 遍历序列中的每个位置 k\n",
    "    for k in range(seq_len):\n",
    "        # 遍历每个偶数维度 i（即 2i 和 2i+1）\n",
    "        for i in np.arange(int(d / 2)):\n",
    "            # 计算分母，分母是 n^(2i/d)，用于调整正弦和余弦函数的频率\n",
    "            denominator = np.power(n, 2 * i / d)\n",
    "            \n",
    "            # 计算正弦值，并存储在偶数维度 2i 中\n",
    "            P[k, 2 * i] = np.sin(k / denominator)\n",
    "            \n",
    "            # 计算余弦值，并存储在奇数维度 2i+1 中\n",
    "            P[k, 2 * i + 1] = np.cos(k / denominator)\n",
    "    \n",
    "    # 返回位置编码矩阵 P\n",
    "    return P\n",
    "\n",
    "# 示例调用\n",
    "P = getPositionEncoding(seq_len=5, d=4, n=100)\n",
    "print(P)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "danwen",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
